
import mjin2
from Common import *
from GameXML import *

class SceneSerializer(object):
    def __init__(self, pathResolver, sceneNodeFactory):
        self.pathResolver = pathResolver
        self.sceneNodeFactory = sceneNodeFactory
    def load(self, gameScene, fileName):
        self.gameScene = gameScene
        self.scene = gameScene.scene
        xml = GameXML(self.pathResolver)
        node = xml.loadAndDereference(fileName)
        s = node.nodes[0]
        if (s.name == "Scene"):
            for c in s.nodes:
                if ((c.name == "OnStart") or
                    (c.name == "OnFinish")):
                    self.gameScene.addListener(c.name, c.nodes[0].value)
                else:
                    self._loadNode(c, self.scene)
        print "before del"
        del xml
        print "after del"
    def _loadLight(self, node):
        # Only one light exists in the scene so far.
        light = self.scene.light()
        # Parameters.
        for c in node.nodes:
            if (c.name == "Ambient"):
                light.setAmbient(readVec4(c))
            elif (c.name == "Diffuse"):
                light.setDiffuse(readVec4(c))
            elif (c.name == "Position"):
                light.setPosition(readVec4(c))
    def _loadNode(self, node, parent):
        attrs  = self._loadNodeAttrs(node)
        params = self._loadNodeParams(node)
        sceneNode = None
        print node.name, node
        if (node.name == "Camera"):
            sceneNode = self.sceneNodeFactory.createCamera(attrs["Name"])
        elif (node.name == "Group"):
            sceneNode = self.sceneNodeFactory.createGroup(attrs["Name"])
        elif (node.name == "Light"):
            sceneNode = self.sceneNodeFactory.createLight(attrs["Name"])
            l = self.scene.light()
            sceneNode.setLight(l)
            # Ambient.
            if ("Ambient" in params):
                l.setAmbient(readVec4(params["Ambient"]))
            # Diffuse.
            if ("Diffuse" in params):
                l.setDiffuse(readVec4(params["Diffuse"]))
        elif (node.name == "Mesh"):
            sceneNode = self.sceneNodeFactory.createMesh(
                attrs["Name"],
                self.pathResolver.findFile(attrs["Mesh"]))
            # Texture.
            if ("Texture" in attrs):
                sceneNode.setTexture(self.pathResolver.findFile(attrs["Texture"]))
            # CastShadows.
            if ("CastShadows" in attrs):
                self.scene.setChildCastShadow(sceneNode, strToBool(attrs["CastShadows"]))
        # Add to parent.
        parent.addChild(sceneNode)
        self._loadNodeOrientation(sceneNode, params)
        # Child nodes.
        for p in params:
            if ((p == "Camera") or
                (p == "Group")  or
                (p == "Light")  or
                (p == "Mesh")):
                self._loadNode(params[p], sceneNode)
    def _loadNodeAttrs(self, node):
        attrs = {}
        for a in node.attrs:
            attrs[a.name] = a.value
        return attrs
    def _loadNodeOrientation(self, sceneNode, params):
        if ("Position" in params):
            sceneNode.setPosition(readVec3(params["Position"]))
        if ("Rotation" in params):
            sceneNode.setRotation(
                mjin2.degreeToQuaternion(readVec3(params["Rotation"])))
        if ("Scale" in params):
            sceneNode.setScale(readVec3(params["Scale"]))
    def _loadNodeParams(self, node):
        params = {}
        for c in node.nodes:
            params[c.name] = c
        return params

